package test.cluster;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import test.client.executor.Client;
import test.cluster.MessagePacket.Type;
import test.cluster.net.connector.Connector;
import test.cluster.net.connector.MinaConnector;
import test.cluster.net.listener.Listener;
import test.cluster.net.listener.MinaListener;
import test.configuration.ConfigFactory;
import test.domain.environment.Cluster;

public class ClusterManager {
	private Log log = LogFactory.getLog(this.getClass());
	private Cluster config = ConfigFactory.getConfiguration().getCluster();
	private String testClass = ConfigFactory.getConfiguration().getTestClass();
	
	private Listener listener;
	private Connector connector;
	
	public void startCluster() {
		String nodeType;
		if (config.isMaster()) {
			nodeType = "master";
		}
		else {
			nodeType = "client";
		}
		
		log.info("start cluster as " + nodeType + "...");
		
		try {
			if (config.isMaster()) {
				// connect clients
				connector = new MinaConnector();
				connector.initialize(config.getClients()).connect();
				
				// order clients to execute
				connector.send(Type.start);
				
				// run test
				Client client = (Client) Class.forName(testClass).newInstance();
//				client.execute();
			}
			else {
				// start listener
				listener = new MinaListener();
				listener.initialize(config.getListener()).start();
			}
		}
		catch (Exception e) {
			log.error(e);
		}
	}
	
	public void stopCluster() {
		log.info("stopping cluster...");
		
		if (config.isMaster()) {
			if (connector == null) 
				throw new IllegalStateException("connector was not initialized.");
			
			connector.disconnect();
			log.info("all connectors are stopped.");
		}
		else {
			if (listener == null)
				throw new IllegalStateException("listener was not initialized.");
			
			listener.stop();
		}
	}
	
	public static void main(String[] args) throws InterruptedException {
		ClusterManager manager = new ClusterManager();
		manager.startCluster();
		
		Thread.sleep(5000);
		
//		manager.stopCluster();
	}
}
